package com.aliengen.thingple.driverapp.device;

import android.util.Log;

import com.aliengen.thingple.beep.DevBeep;
import com.aliengen.thingple.cmc168mwithservice.Common;
import com.aliengen.thingple.driverapp.data.exception.InvalidTagException;
import com.aliengen.thingple.driverapp.data.local.Preferences;
import com.aliengen.thingple.driverapp.data.models.CylinderTag;
import com.aliengen.thingple.driverapp.data.models.TruckTag;
import com.aliengen.thingple.driverapp.service.HandsetApplication;

import java.util.HashMap;

/**
 * This class is part of the Thingple mobile application for the CMC168 Handheld reader.
 *
 * Copyright AlienGen Limited 2016. All rights reserved.
 *
 * @author Timothé Mermet-Buffet <tim@aliengen.com>
 */
public class BatchReadThread extends Thread {
    protected HandsetApplication mApplication;
    protected Boolean isReading = false;
    public static HashMap<String,CylinderTag> cylindersList = new HashMap<String, CylinderTag>();

    protected ReadingListener mListener = null;

    public static int operationId = 0;
    public static TruckTag truckTag = null;

    public interface ReadingListener {
        public Boolean validate(CylinderTag tag);
        public void onReadingException(Exception e);
    }

    public BatchReadThread(HandsetApplication application, ReadingListener listener)
    {
        this.mApplication = application;
        this.mListener = listener;
    }

    public void setReadingListener(ReadingListener listener)
    {
        this.mListener = listener;
    }

    public void stopReading()
    {
        this.isReading = false;
        try {
            Thread.sleep(200);
        } catch(InterruptedException e) {
            e.printStackTrace();
        }
    }

    public void start()
    {
        this.isReading = true;
        super.start();
    }

    public void run()
    {
        /* Set power. */
        int power = Preferences.get(Preferences.SHARE_INVENTORY_READ_POWER, 28);
        mApplication.mService.device.setPower(power);
        mApplication.mService.device.startInventory();

        Boolean newReading = false;
        while(this.isReading == true)
        {
            try{
                sleep(100);
            }
            catch (InterruptedException e){e.printStackTrace();}
            try
            {
                int cnt = mApplication.mService.device.getSize();
                for(int j = 0;j < cnt; j++)
                {
                    String epc = mApplication.mService.device.getItem();
                    byte[] epc_b = new byte[16];
                    Common.hexStr2Bytes(epc, epc_b, 0, 16);

                    Log.i("BatchReadThread", "EPC Size: " + epc_b.length);
                    Log.i("BatchReadThread", "Read epc: " + epc);

                    if(cylindersList.containsKey(epc))
                    {
                        Log.i("BatchReadThread", "Tag already in the HashMap!");
                        continue;
                    }

                    try
                    {
                        CylinderTag tag = CylinderTag.get(epc_b);

                        if(mListener != null)
                        {
                            if(mListener.validate(tag))
                            {
                                Log.i("BatchReadThread", "Huashen: " + tag.getReference());
                                tag.getCylinder().operationId = BatchReadThread.operationId;
                                tag.getCylinder().truckTag = BatchReadThread.truckTag;
                                cylindersList.put(epc, tag);
                                DevBeep.PlayOK();
                                newReading = true;
                            }
                        }
                    } catch(InvalidTagException e) {
                        if(mListener != null)
                        {
                            mListener.onReadingException(e);
                        }
                    }
                }
                mApplication.mService.device.resetItems();
                if(newReading)
                {
                    newReading = false;
                    mApplication.getHandler().obtainMessage(CMCHandler.RET_RECEIVE_DATA).sendToTarget();
                    try {sleep(150);} catch (InterruptedException e) {}
                }

                /**
                 * Dirty part to catch the events of the trigger
                 */
                mApplication.mService.device.stopInventory();
                try {sleep(250);} catch (InterruptedException e) {}
                mApplication.mService.device.startInventory();
            }
            catch(Exception e)
            {
                e.printStackTrace();
            }
        }
        mApplication.mService.device.stopInventory();
        mApplication.mService.device.resetItems();
    }
}
